package com.hb.trade.server.flow.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb.core.pojo.flow.mapper.FlowMainMapper;
import com.hb.core.pojo.flow.entity.*;
import com.hb.core.pojo.flow.dto.FlowTempFormFieldDTO;
import com.hb.core.pojo.flow.dto.FlowTempMainDTO;
import com.hb.core.pojo.flow.dto.FlowTempNodeDTO;
import com.hb.core.pojo.flow.dto.FlowTempTaskDTO;
import com.hb.trade.server.flow.manager.FlowTempTaskManager;
import com.hb.trade.server.flow.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 流程主表 服务实现类
 * </p>
 *
 * @author zhaojk
 * @since 2021-05-27
 */
@Service
public class FlowMainServiceImpl extends ServiceImpl<FlowMainMapper, FlowMain> implements FlowMainService {

    protected final FlowFormService flowFormService;
    protected final FlowTempNodeService flowTempNodeService;
    protected final FlowNodeService flowNodeService;
    protected final FlowApproverService flowApproverService;

    public FlowMainServiceImpl(FlowFormService flowFormService,
                               FlowTempNodeService flowTempNodeService,
                               FlowNodeService flowNodeService,
                               FlowApproverService flowApproverService) {
        this.flowFormService = flowFormService;
        this.flowTempNodeService = flowTempNodeService;
        this.flowNodeService = flowNodeService;
        this.flowApproverService = flowApproverService;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean launchFlow(FlowTempMainDTO flowTempMainDto) {
        Long flowTempId = flowTempMainDto.getId();
        /* ************************** 保存流程主表信息 ************************** */
        FlowMain main = new FlowMain();
        // 流程发起人
        main.setUserId(flowTempMainDto.getUserId());
        // 流程模板ID
        main.setTempMainId(flowTempId);
        // 生成随机流程号
        main.getRandomFlowNum();
        // 正在执行的审批节点, 默认第一个
        main.setCurrentNodeIndex(1);

        main.buildBaseData(1);
        save(main);

        /* ************************** 保存流程表单信息 ************************** */
        List<FlowTempFormFieldDTO> fieldDtos = flowTempMainDto.getFormFields();
        Collection<FlowFormField> fields =
                CollUtil.trans(fieldDtos, (fieldDto) -> {
                    FlowFormField flowFormField = fieldDto.to(FlowFormField.class);
                    flowFormField.setFieldValue(fieldDto.getFieldValue());
                    return flowFormField;
                });
        flowFormService.saveBatch(fields);

        /* ************************** 保存审批流程节点信息 ************************** */
        List<FlowTempNodeDTO> nodes = flowTempNodeService.listFlowTempNodes(flowTempId);
        for (FlowTempNodeDTO nodeDto : nodes) {
            // 保存审批节点
            FlowNode node = nodeDto.to(FlowNode.class);
            node.setMainId(main.getId());
            node.buildBaseData(1);
            flowNodeService.save(node);

            // 保存审批任务
            List<FlowTempTaskDTO> taskDtos = nodeDto.getTempTasks();

            // 计算审批任务
            FlowTempTaskDTO finalTask = null;
            if (taskDtos.size() == 1) {
                finalTask = taskDtos.get(0);
            } else {
                // 获取表单的输入值
                for (FlowTempTaskDTO taskDto : taskDtos) {
                    FlowTempTaskManager taskManager = taskDto.to(FlowTempTaskManager.class);
                    boolean r = taskManager.eval(fields);
                    if (r) {
                        finalTask = taskDto;
                        break;
                    }
                }
            }

            if (finalTask == null) {
                continue;
            }

            // 流程模板中的审批人
            List<FlowTempApprover> approvers = finalTask.getApprovers();
            // 将要保存的审批人
            List<FlowApprover> saveApprovers = CollUtil.list(false);

            for (FlowTempApprover approver : approvers) {
                // 设置的审批人类型
                Integer approverType = approver.getApproverType();
                List<FlowApprover> approverList = null;
                switch (approverType) {
                    case 1: // 部门
//                        approverList = adminUserClient.listUsersByDeptId(approver.getApproverId());
//                        break;
                    case 2: // 用户
                        FlowApprover saveApprover = approver.to(FlowApprover.class);
                        saveApprover.setNodeId(node.getId());
                        saveApprover.buildBaseData(1);
                        saveApprovers.add(saveApprover);
                        break;
                    case 3: // 角色
//                        approverList = adminUserClient.listUsersByRoleId(approver.getApproverId());
//                        break;
                    default:
                }
                if (approverList != null && approverList.size() > 0) {
                    for (FlowApprover flowApprover : approverList) {
                        flowApprover.setNodeId(node.getId());
                        flowApprover.buildBaseData(1);
                    }
                    saveApprovers.addAll(approverList);
                }
            }
            flowApproverService.saveBatch(saveApprovers);
        }
        return true;
    }

    @Override
    public IPage<JSONObject> todoByUserId(FlowApprover approver) {
        IPage<JSONObject> pages = approver.pages();
        return baseMapper.todoList(pages, approver);
    }
}
